#pragma once

#include <cassert>
#include "ShmMessagePool.hpp"

class ShmMessageNodeQueue
{
public:
    // 构造函数，接受队列容量和共享消息池
    ShmMessageNodeQueue(uint32_t capacity)
        : _size(0)
        , _capacity(capacity)
        , _head(-1)
        , _tail(-1) {}

    ~ShmMessageNodeQueue() {}


    // 入队操作，将节点加入队尾
    void Push_Back(ShmMessageNode* node, ShmMessagePool& pool) {
        assert(node != nullptr); // 确保传入节点不为空
        assert(_size < _capacity); // 确保队列未满

        // 如果队列为空，设置头和尾指针为新节点
        if (_tail == -1) {
            _head = _tail = node->GetNodePos();
            node->SetNext(-1);
        }
        else {
            // 否则，将新节点添加到队尾
            ShmMessageNode* tailNode = pool.FindAllocatedNodeByPos(_tail);
            assert(tailNode != nullptr); // 确保尾部节点存在

            tailNode->SetNext(node->GetNodePos());
            node->SetNext(-1);
            _tail = node->GetNodePos();
        }

        _size++;
    }

    // 出队操作，从队头移除节点
    void Pop(ShmMessagePool& pool) {
        assert(_head != -1); // 确保队列不为空

        // 拿到队首节点
        ShmMessageNode* headNode = pool.FindAllocatedNodeByPos(_head);
        assert(headNode != nullptr); // 确保头部节点存在

        _head = headNode->GetNext();
        _size--;

        // 如果队列为空，重置尾指针
        if (_head == -1) {
            _tail = -1;
        }
    }

    // 获取队头节点
    ShmMessageNode* Front(ShmMessagePool& pool) {
        assert(_head != -1); // 确保队列不为空

        ShmMessageNode* headNode = pool.FindAllocatedNodeByPos(_head);
        assert(headNode != nullptr); // 确保头部节点存在

        return headNode;
    }

    // 获取队尾节点
    ShmMessageNode* Back(ShmMessagePool& pool) {
        assert(_tail != -1); // 确保队列不为空

        ShmMessageNode* tailNode = pool.FindAllocatedNodeByPos(_tail);
        assert(tailNode != nullptr); // 确保尾部节点存在

        return tailNode;
    }

    // 检查指定节点是否是队头
    bool isHead(ShmMessageNode* node) {
        return _head == node->GetNodePos();
    }

    // 检查队列是否为空
    bool Empty() const {
        return _size == 0;
    }

    // 检查队列是否已满
    bool Full() const {
        return _size >= _capacity;
    }

    // 返回队列节点数量
    uint32_t Size() const {
        return _size;
    }

    // 清空队列
    void Clear(ShmMessagePool& pool) {
        while (_head != -1) {
            Pop(pool);
        }
    }


private:
    uint32_t _size;      // 当前队列节点数量
    uint32_t _capacity;  // 队列最大容量
    int _head;           // 指向队头的偏移量
    int _tail;           // 指向队尾的偏移量
};